<template>
  <div id="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
//引入cesium 引入样式 引入生命周期挂载
import * as Cesium from 'cesium';
import './Widgets/widgets.css';
import { onMounted } from 'vue';

//设置cesium token
Cesium.Ion.defaultAccessToken =
  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0MGNkNzY3YS1mMDcxLTQ0NjQtOTlhMC00Y2Y0MjA3ZGQ1ZTIiLCJpZCI6MjY0NzQyLCJpYXQiOjE3MzUwOTQ0NzF9.09AnFzH3aVpi7s-0WqcAYuf69lr4UUIbKL4DmKBf1qg';

//设置根目录静态资源 /代表根目录public
window.CESIUM_BASE_URL = '/';

onMounted(async () => {
  console.log('Cesium', Cesium);
  const viewer = new Cesium.Viewer('cesiumContainer', {
    // 是否显示信息窗口
    infoBox: false,
  });

  //动态设置默认颜色
  // let material = new Cesium.ColorMaterialProperty(
  //   new Cesium.Color(1.0, 1.0, 1.0, 1.0)
  // );
  // console.log('material', material);

  //动态设置官方示例的网格纹理
  let material = new Cesium.CheckerboardMaterialProperty({
    evenColor: Cesium.Color.RED,
    oddColor: Cesium.Color.GREEN,
    repeat: new Cesium.Cartesian2(4, 4),
  });

  //entity创建矩形
  var rectangle = viewer.entities.add({
    id: 'entityRect',
    //配置矩形
    rectangle: {
      //配置矩形的经纬度 两个点(西纬度和南纬度  东经度北纬度 两个点形成矩形)
      coordinates: Cesium.Rectangle.fromDegrees(
        //西边的经度
        90,
        //南边的纬度
        20,
        //东边的经度
        110,
        //北边的纬度
        30
      ),
      //设置实体材质属性MaterialProperty
      material: material,
    },
  });

  //primivite创建矩形
  //1.创建几何体
  let rectGeometry = new Cesium.RectangleGeometry({
    rectangle: Cesium.Rectangle.fromDegrees(
      //西边的经度
      115,
      //南边的纬度
      20,
      //东边的经度
      130,
      //北边的纬度
      30
    ),
    //挤出高度(距离表面高度)
    height: 30,
    //顶点格式(颜色 纹理 法线 反射光)  EllipsoidSurfaceAppearance:椭球体表面
    vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
  });

  let rectGeometry1 = new Cesium.RectangleGeometry({
    rectangle: Cesium.Rectangle.fromDegrees(
      //西边的经度
      140,
      //南边的纬度
      20,
      //东边的经度
      160,
      //北边的纬度
      30
    ),
    //挤出高度(距离表面高度)
    height: 30,
    //顶点格式(颜色 纹理 法线 反射光)  EllipsoidSurfaceAppearance:椭球体表面
    vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
  });

  //创建几何体实例
  let instance = new Cesium.GeometryInstance({
    id: 'redRect',
    geometry: rectGeometry,
    //目的 颜色属性
    attributes: {
      color: Cesium.ColorGeometryInstanceAttribute.fromColor(
        Cesium.Color.RED.withAlpha(0.5)
      ),
    },
  });

  let instance2 = new Cesium.GeometryInstance({
    id: 'blueRect',
    geometry: rectGeometry1,
    //目的 颜色属性
    attributes: {
      color: Cesium.ColorGeometryInstanceAttribute.fromColor(
        Cesium.Color.BLUE.withAlpha(0.5)
      ),
    },
  });

  //使用instance的颜色去着色
  // let material1 = new Cesium.Material({
  //   fabric: {
  //     type: 'Color',
  //     uniforms: {
  //       color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
  //     },
  //   },
  // });

  //type Image
  // let material1 = new Cesium.Material({
  //   fabric: {
  //     type: 'Image',
  //     uniforms: {
  //       image: './texture/logo.png',
  //     },
  //   },
  // });

  //自定义编写着色器修改材质
  let material1 = new Cesium.Material({
    strict: false,
    fabric: {
      //参数
      uniforms: {},
      type: 'Water',
      source: `
        czm_material czm_getMaterial(czm_materialInput materialInput)
{
    czm_material material = czm_getDefaultMaterial(materialInput);

    float time = czm_frameNumber * animationSpeed_5;

    // fade is a function of the distance from the fragment and the frequency_4 of the waves
    float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency_4 * fadeFactor_8);

    float specularMapValue = texture(specularMap_2, materialInput.st).r;

    // note: not using directional motion at this time, just set the angle to 0.0;
    vec4 noise = czm_getWaterNoise(normalMap_3, materialInput.st * frequency_4, time, 0.0);
    vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude_6));

    // fade out the normal perturbation as we move further from the water surface
    normalTangentSpace.xy /= fade;

    // attempt to fade out the normal perturbation as we approach non water areas (low specular map value)
    normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);

    normalTangentSpace = normalize(normalTangentSpace);

    // get ratios for alignment of the new normal vector with a vector perpendicular to the tangent plane
    float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);

    // fade out water effect as specular map value decreases
    material.alpha = mix(blendColor_1.a, baseWaterColor_0.a, specularMapValue) * specularMapValue;

    // base color is a blend of the water and non-water color based on the value from the specular map
    // may need a uniform blend factor to better control this
    material.diffuse = vec3(1.0,0.0,0.0);

    // diffuse highlights are based on how perturbed the normal is
    material.diffuse += (0.1 * tsPerturbationRatio);

    material.diffuse = material.diffuse;

    material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);

    material.specular = specularIntensity_7;
    material.shininess = 10.0;

    return material;
}
      `,
    },
  });

  console.log('source', material1.shaderSource);

  //设定几何体都是与地球椭球体平行
  //假定几何体与地球椭球体平行,就可以再计算大量顶点属性的时候节省内存
  let appearance = new Cesium.EllipsoidSurfaceAppearance({
    material: material1,
    aboveGround: false,
  });

  //原始基类写法 没有计算好的写法 性能差
  // let appearance = new Cesium.MaterialAppearance({
  //   material: material1,
  // });

  //创建图元
  let primivite = new Cesium.Primitive({
    geometryInstances: [instance, instance2],
    //材质
    appearance: appearance,
  });
  //添加到viewer场景中
  viewer.scene.primitives.add(primivite);

  //设置相机位置
  // viewer.flyTo(viewer.entities);
});
</script>

<style>
/* 初始化边距 */
* {
  margin: 0;
  padding: 0;
}
/* 初始化模型和屏幕占位 */
#cesiumContainer {
  width: 100vw;
  height: 100vh;
}
</style>
